package com.gitee.wsl.ext.list

import kotlin.math.min


/**
 * Adds items after the index meeting a [predicateIndex]
 */
fun <T> MutableList<T>.addAfterIndexInLine(
    predicateIndex: (T) -> Boolean,
    items: List<T>
) {
    val newIndex = indexOfFirst(predicateIndex)
    if (newIndex in 0 until size) {
        addAll(newIndex + 1, items)
    } else {
        addAll(size, items)
    }
}

/**
 * Moves all items meeting a [predicateMove] after the index meeting a [predicateIndex]
 */
fun <T> MutableList<T>.moveAfterIndexInLine(
    predicateIndex: (T) -> Boolean,
    predicateMove: (T) -> Boolean
) {
    val split = partition(predicateMove)
    clear()
    addAll(split.second)
    val newIndex = indexOfFirst(predicateIndex)
    if (newIndex in 0 until size) {
        addAll(newIndex + 1, split.first)
    } else {
        addAll(size, split.first)
    }
}

fun <T:Comparable<T>> List<T>.next(current:T,defaultIndex:Int = 0) = prevOrNext(current, defaultIndex  ,true)

fun <T:Comparable<T>> List<T>.prev(current:T,defaultIndex:Int = 0) = prevOrNext(current, defaultIndex  ,false)

private fun <T:Comparable<T>> List<T>.prevOrNext(current:T,defaultIndex:Int = 0, increase: Boolean = true):T{
    val currentIndex = indexOfFirst { it >= current }
    val safeCurrentIndex = if (currentIndex == -1) defaultIndex else currentIndex

    val newIndex = if (increase) {
        (safeCurrentIndex + 1).coerceAtMost(size - 1)
    } else {
        (safeCurrentIndex - 1).coerceAtLeast(0)
    }

    return get(newIndex)
}